package com.kwdb.sdk.examples;

import com.kwdb.sdk.KWDBClient;
import com.kwdb.sdk.config.ClientConfig;
import com.kwdb.sdk.data.DataPoint;
import com.kwdb.sdk.query.QueryResult;
import com.kwdb.sdk.query.QueryBuilder;
import com.kwdb.sdk.exception.KWDBException;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * KWDB SDK基础使用示例 - 基于gRPC的高性能SDK
 */
public class BasicExample {
    
    public static void main(String[] args) {
        // 创建客户端配置
        ClientConfig config = new ClientConfig("localhost", 9090)
                .setBatchSize(1000)
                .setBatchTimeout(100)
                .setThreadPoolSize(10)
                .setEnableCompression(true)
                .setKeepAlive(true);
        
        // 创建客户端
        KWDBClient client = new KWDBClient(config);
        
        try {
            // 连接服务器
            System.out.println("正在连接KWDB服务器...");
            client.connect();
            System.out.println("连接成功！");
            
            // 示例1: 写入单条数据
            System.out.println("\n=== 示例1: 写入单条数据 ===");
            writeSingleDataPoint(client);
            
            // 示例2: 批量写入数据
            System.out.println("\n=== 示例2: 批量写入数据 ===");
            writeBatchData(client);
            
            // 示例3: 异步写入数据
            System.out.println("\n=== 示例3: 异步写入数据 ===");
            writeDataAsync(client);
            
            // 示例4: 流式写入数据
            System.out.println("\n=== 示例4: 流式写入数据 ===");
            writeDataStream(client);
            
            // 示例5: 查询数据
            System.out.println("\n=== 示例5: 查询数据 ===");
            queryData(client);
            
            // 示例6: 使用查询构建器
            System.out.println("\n=== 示例6: 使用查询构建器 ===");
            queryWithBuilder(client);
            
            // 示例7: 流式查询
            System.out.println("\n=== 示例7: 流式查询 ===");
            queryStreamData(client);
            
            // 示例8: Line Protocol解析
            System.out.println("\n=== 示例8: Line Protocol解析 ===");
            parseLineProtocol(client);
            
            // 等待异步操作完成
            Thread.sleep(2000);
            
        } catch (Exception e) {
            System.err.println("操作失败: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 断开连接
            client.disconnect();
            System.out.println("\n连接已断开");
        }
    }
    
    /**
     * 写入单条数据示例
     */
    private static void writeSingleDataPoint(KWDBClient client) throws KWDBException {
        // 创建数据点
        DataPoint dataPoint = new DataPoint("temperature")
                .addTag("location", "beijing")
                .addTag("device", "sensor001")
                .addField("value", 25.5)
                .addField("humidity", 60)
                .addField("status", "normal");
        
        // 写入数据
        client.write(dataPoint);
        System.out.println("单条数据写入成功: " + dataPoint.toLineProtocol());
    }
    
    /**
     * 批量写入数据示例
     */
    private static void writeBatchData(KWDBClient client) throws KWDBException {
        List<DataPoint> dataPoints = new ArrayList<>();
        
        // 创建多个数据点
        for (int i = 0; i < 5; i++) {
            DataPoint dataPoint = new DataPoint("pressure")
                    .addTag("location", "shanghai")
                    .addTag("device", "sensor" + String.format("%03d", i))
                    .addField("value", 1013.25 + i)
                    .addField("unit", "hPa")
                    .setTimestamp(System.currentTimeMillis() - (5 - i) * 1000);
            
            dataPoints.add(dataPoint);
        }
        
        // 批量写入
        client.writeBatch(dataPoints);
        System.out.println("批量数据写入成功，共 " + dataPoints.size() + " 条记录");
    }
    
    /**
     * 异步写入数据示例
     */
    private static void writeDataAsync(KWDBClient client) {
        // 创建数据点
        DataPoint dataPoint = new DataPoint("wind_speed")
                .addTag("location", "guangzhou")
                .addTag("device", "weather_station")
                .addField("speed", 15.2)
                .addField("direction", "NE")
                .addField("unit", "m/s");
        
        // 异步写入
        CompletableFuture<Void> future = client.writeAsync(dataPoint);
        future.thenRun(() -> {
            System.out.println("异步数据写入成功: " + dataPoint.toLineProtocol());
        }).exceptionally(throwable -> {
            System.err.println("异步写入失败: " + throwable.getMessage());
            return null;
        });
    }
    
    /**
     * 流式写入数据示例
     */
    private static void writeDataStream(KWDBClient client) {
        List<DataPoint> dataPoints = new ArrayList<>();
        
        // 创建大量数据点
        for (int i = 0; i < 100; i++) {
            DataPoint dataPoint = new DataPoint("sensor_data")
                    .addTag("location", "factory")
                    .addTag("device", "sensor" + i)
                    .addField("value", Math.random() * 100)
                    .addField("timestamp", System.currentTimeMillis() - i * 1000);
            
            dataPoints.add(dataPoint);
        }
        
        // 流式写入
        CompletableFuture<Void> future = client.writeStreamAsync(dataPoints);
        future.thenRun(() -> {
            System.out.println("流式数据写入成功，共 " + dataPoints.size() + " 条记录");
        }).exceptionally(throwable -> {
            System.err.println("流式写入失败: " + throwable.getMessage());
            return null;
        });
    }
    
    /**
     * 查询数据示例
     */
    private static void queryData(KWDBClient client) throws KWDBException {
        // 执行SQL查询
        String sql = "SELECT * FROM temperature WHERE location = 'beijing' LIMIT 10";
        QueryResult result = client.query(sql);
        
        System.out.println("查询结果:");
        System.out.println("列数: " + result.getColumns().size());
        System.out.println("行数: " + result.getRows().size());
        System.out.println("执行时间: " + result.getExecutionTime() + "ms");
        
        // 遍历结果
        for (QueryResult.Row row : result) {
            System.out.println("行数据: " + row);
        }
    }
    
    /**
     * 使用查询构建器示例
     */
    private static void queryWithBuilder(KWDBClient client) throws KWDBException {
        // 使用查询构建器
        QueryResult result = client.queryBuilder()
                .select("location", "device", "value")
                .from("pressure")
                .where("location = 'shanghai'")
                .orderBy("timestamp", "DESC")
                .limit(5)
                .execute();
        
        System.out.println("查询构建器结果:");
        System.out.println("行数: " + result.getRows().size());
        
        // 遍历结果
        for (QueryResult.Row row : result) {
            String location = row.getValue("location");
            String device = row.getValue("device");
            String value = row.getValue("value");
            System.out.println("位置: " + location + ", 设备: " + device + ", 值: " + value);
        }
    }
    
    /**
     * 流式查询示例
     */
    private static void queryStreamData(KWDBClient client) {
        String sql = "SELECT * FROM sensor_data WHERE location = 'factory' LIMIT 1000";
        
        CompletableFuture<QueryResult> future = client.queryStreamAsync(sql);
        future.thenAccept(result -> {
            System.out.println("流式查询结果:");
            System.out.println("行数: " + result.getRows().size());
            System.out.println("执行时间: " + result.getExecutionTime() + "ms");
        }).exceptionally(throwable -> {
            System.err.println("流式查询失败: " + throwable.getMessage());
            return null;
        });
    }
    
    /**
     * Line Protocol解析示例
     */
    private static void parseLineProtocol(KWDBClient client) {
        // 解析Line Protocol格式数据
        String lineProtocol = "cpu,host=server01,region=us-west usage=0.64,idle=0.36 1434055562000000000";
        
        try {
            DataPoint dataPoint = client.parseLineProtocol(lineProtocol);
            System.out.println("解析成功:");
            System.out.println("测量: " + dataPoint.getMeasurement());
            System.out.println("标签: " + dataPoint.getTags());
            System.out.println("字段: " + dataPoint.getFields());
            System.out.println("时间戳: " + dataPoint.getTimestamp());
            
            // 转换回Line Protocol格式
            String converted = client.toLineProtocol(dataPoint);
            System.out.println("转换回Line Protocol: " + converted);
            
        } catch (Exception e) {
            System.err.println("Line Protocol解析失败: " + e.getMessage());
        }
    }
}
